Repository navigation
iroh transport P2: cmux-iroh FFI packaging (crate + xcframework + CI toolchain) - #7813
azooz2003-bit wants to merge 4 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis change adds a Rust-based cmux-iroh C FFI library, packages it into an Apple XCFramework, links it into macOS and iOS projects, provisions it across local and CI build paths, and updates terminal resync handling and deterministic test coverage. Changescmux-iroh FFI
Terminal resync determinism
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related issues
Possibly related PRs
Suggested reviewers: Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors, 1 warning)
✅ Passed checks (22 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 221c7cb. Configure here.
| exit 0 | ||
| fi | ||
| sleep 1 | ||
| done |
There was a problem hiding this comment.
Stale build lock hangs forever
High Severity
The xcframework cache lock wait loop never times out or reclaims a stale lock directory. If a prior ensure-cmux-iroh.sh run is killed after creating the lock but before finishing, later runs spin forever waiting to acquire the lock while the cache artifact never appears.
Reviewed by Cursor Bugbot for commit 221c7cb. Configure here.
| build_number="$(date -u +%Y%m%d%H%M%S)" | ||
| ARCHIVE_PATH="$out/cmux-ios-beta.xcarchive" | ||
| [[ -x "$REPO_ROOT/scripts/ensure-ghosttykit.sh" ]] && ( cd "$REPO_ROOT" && ./scripts/ensure-ghosttykit.sh ) || true | ||
| [[ -x "$REPO_ROOT/scripts/ensure-cmux-iroh.sh" ]] && ( cd "$REPO_ROOT" && ./scripts/ensure-cmux-iroh.sh ) || true |
There was a problem hiding this comment.
Local archive ignores iroh provision
Medium Severity
Local TestFlight archive builds now call ensure-cmux-iroh.sh but append || true, so a non-zero exit from provisioning is ignored. The script continues to xcodebuild archive without CmuxIrohFFI.xcframework, producing a confusing link error instead of surfacing the provisioning failure.
Reviewed by Cursor Bugbot for commit 221c7cb. Configure here.
Greptile SummaryThis PR packages the new iroh transport FFI for Apple builds. The main changes are:
Confidence Score: 5/5This looks safe to merge from the latest reviewed changes.
Important Files Changed
Reviews (3): Last reviewed commit: "Fix iOS lane identity guard provisioning" | Re-trigger Greptile |
| if connection.is_null() { | ||
| return; | ||
| } | ||
| let connection = unsafe { Box::from_raw(connection) }; |
There was a problem hiding this comment.
When Swift closes a connection while another queue is blocked in cmux_iroh_connection_recv() or cmux_iroh_connection_send(), this reconstructs and drops the Box<CmuxIrohConnection> even though those functions may still hold references into the same allocation. The handle API exposes blocking calls and per-stream mutexes, so teardown needs shared lifetime ownership or a closed state instead of freeing the raw pointer while in-flight operations can still use it.
| if endpoint.is_null() { | ||
| return; | ||
| } | ||
| let endpoint = unsafe { Box::from_raw(endpoint) }; |
There was a problem hiding this comment.
When an endpoint is closed from teardown while accept, online, connect, or route_json is already running, this drops the boxed endpoint after those functions have converted the raw pointer with endpoint.as_ref(). A concurrent close can free the allocation backing an in-flight blocking call, so callers can get undefined behavior instead of a clean endpoint-closed result.
| while ! mkdir "${LOCK_DIR}" 2>/dev/null; do | ||
| if [ -d "${CACHE_XCFRAMEWORK}" ]; then | ||
| link_local_xcframework "${CACHE_XCFRAMEWORK}" | ||
| echo "using cached ${LOCAL_XCFRAMEWORK}" | ||
| exit 0 | ||
| fi | ||
| sleep 1 | ||
| done |
There was a problem hiding this comment.
If the first ensure-cmux-iroh.sh process is killed after creating ${LOCK_DIR} but before the trap removes it, later setup.sh, reload.sh, or CI provisioning runs for the same source hash loop here forever because the cached xcframework never appears. This new build prerequisite needs stale-lock recovery or a bounded wait so interrupted Rust builds do not permanently wedge app builds until the hidden lock directory is deleted by hand.
Rule Used: Flag fixed sleeps, delayed dispatch, timers, polli... (source)
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/ios-testflight.yml:
- Around line 369-374: Update the iosPathPattern path gate to include
native/cmux-iroh/** and scripts/ensure-cmux-iroh.sh, ensuring scheduled runs
with only cmux-iroh FFI or provisioning changes set needsBuild=true and archive
the newly provisioned framework.
In `@scripts/ensure-cmux-iroh.sh`:
- Around line 109-117: Replace the unbounded mkdir polling loop around LOCK_DIR
with an event-driven flock acquisition when available, or a bounded retry
mechanism with a maximum attempt count and explicit failure handling. Preserve
the cached CACHE_XCFRAMEWORK fast path and ensure lock cleanup/release is
handled correctly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 94bf8464-ddbc-4928-a316-f65d1caf1183
⛔ Files ignored due to path filters (1)
native/cmux-iroh/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (26)
.github/workflows/ci-macos-compat.yml.github/workflows/ci.yml.github/workflows/ios-app-store.yml.github/workflows/ios-testflight.yml.github/workflows/nightly.yml.github/workflows/perf-activation.yml.github/workflows/release.yml.github/workflows/reload-build.yml.github/workflows/test-depot.yml.github/workflows/test-e2e.yml.github/workflows/test-ios.yml.github/workflows/tmux-corpus.yml.gitignorecmux.xcodeproj/project.pbxprojios/cmux-ios.xcodeproj/project.pbxprojios/scripts/cloud-testflight.shios/scripts/reload.shios/scripts/upload-testflight.shnative/cmux-iroh/.gitignorenative/cmux-iroh/Cargo.tomlnative/cmux-iroh/include/cmux_iroh_ffi.hnative/cmux-iroh/src/lib.rsscripts/ensure-cmux-iroh.shscripts/install-rust-ci.shscripts/reload.shscripts/setup.sh
| - name: Provision cmux-iroh FFI | ||
| run: | | ||
| ./scripts/install-rust-ci.sh | ||
| export PATH="$HOME/.cargo/bin:$PATH" | ||
| ./scripts/ensure-cmux-iroh.sh | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Include the cmux-iroh inputs in the scheduled-upload path gate.
The iosPathPattern at Line 244 does not match native/cmux-iroh/** or scripts/ensure-cmux-iroh.sh. A scheduled run containing only an FFI or packaging change can therefore set needsBuild=false and skip archiving the newly provisioned framework.
Proposed fix
- const iosPathPattern = /^(ios\/|Packages\/Shared\/|Packages\/iOS\/|Sources\/Mobile\/|vendor\/stack-auth-swift-sdk-prerelease\/|ghostty$|scripts\/ensure-ghosttykit\.sh$|scripts\/ghosttykit-checksums\.txt$|scripts\/install-zig-ci\.sh$|\.github\/workflows\/ios-testflight\.yml$)/;
+ const iosPathPattern = /^(ios\/|native\/cmux-iroh\/|Packages\/Shared\/|Packages\/iOS\/|Sources\/Mobile\/|vendor\/stack-auth-swift-sdk-prerelease\/|ghostty$|scripts\/ensure-cmux-iroh\.sh$|scripts\/ensure-ghosttykit\.sh$|scripts\/ghosttykit-checksums\.txt$|scripts\/install-zig-ci\.sh$|\.github\/workflows\/ios-testflight\.yml$)/;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - name: Provision cmux-iroh FFI | |
| run: | | |
| ./scripts/install-rust-ci.sh | |
| export PATH="$HOME/.cargo/bin:$PATH" | |
| ./scripts/ensure-cmux-iroh.sh | |
| const iosPathPattern = /^(ios\/|native\/cmux-iroh\/|Packages\/Shared\/|Packages\/iOS\/|Sources\/Mobile\/|vendor\/stack-auth-swift-sdk-prerelease\/|ghostty$|scripts\/ensure-cmux-iroh\.sh$|scripts\/ensure-ghosttykit\.sh$|scripts\/ghosttykit-checksums\.txt$|scripts\/install-zig-ci\.sh$|\.github\/workflows\/ios-testflight\.yml$)/; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/ios-testflight.yml around lines 369 - 374, Update the
iosPathPattern path gate to include native/cmux-iroh/** and
scripts/ensure-cmux-iroh.sh, ensuring scheduled runs with only cmux-iroh FFI or
provisioning changes set needsBuild=true and archive the newly provisioned
framework.
| LOCK_DIR="${CACHE_ROOT}/.${BUILD_KEY}.lock" | ||
| while ! mkdir "${LOCK_DIR}" 2>/dev/null; do | ||
| if [ -d "${CACHE_XCFRAMEWORK}" ]; then | ||
| link_local_xcframework "${CACHE_XCFRAMEWORK}" | ||
| echo "using cached ${LOCAL_XCFRAMEWORK}" | ||
| exit 0 | ||
| fi | ||
| sleep 1 | ||
| done |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Replace sleep 1 polling loop with a bounded or event-driven lock mechanism.
The sleep 1 inside the while loop is a fixed delay used as synchronization in a polling loop, which the coding guidelines prohibit in shell scripts. If the building process hangs indefinitely, this loop spins forever with no timeout. Consider using flock for blocking lock acquisition, or add a bounded retry count to prevent unbounded spinning.
♻️ Proposed fix: bounded retry with flock fallback
LOCK_DIR="${CACHE_ROOT}/.${BUILD_KEY}.lock"
-MAX_WAIT=3600 # 1 hour max wait for another build
-WAITED=0
-while ! mkdir "${LOCK_DIR}" 2>/dev/null; do
- if [ -d "${CACHE_XCFRAMEWORK}" ]; then
- link_local_xcframework "${CACHE_XCFRAMEWORK}"
- echo "using cached ${LOCAL_XCFRAMEWORK}"
- exit 0
- fi
- sleep 1
-done
+MAX_WAIT=3600
+WAITED=0
+while ! mkdir "${LOCK_DIR}" 2>/dev/null; do
+ if [ -d "${CACHE_XCFRAMEWORK}" ]; then
+ link_local_xcframework "${CACHE_XCFRAMEWORK}"
+ echo "using cached ${LOCAL_XCFRAMEWORK}"
+ exit 0
+ fi
+ WAITED=$((WAITED + 1))
+ if [ "$WAITED" -ge "$MAX_WAIT" ]; then
+ echo "error: timed out after ${MAX_WAIT}s waiting for build lock" >&2
+ exit 1
+ fi
+ sleep 1
+done🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@scripts/ensure-cmux-iroh.sh` around lines 109 - 117, Replace the unbounded
mkdir polling loop around LOCK_DIR with an event-driven flock acquisition when
available, or a bounded retry mechanism with a maximum attempt count and
explicit failure handling. Preserve the cached CACHE_XCFRAMEWORK fast path and
ensure lock cleanup/release is handled correctly.
Sources: Coding guidelines, Path instructions
This comment has been minimized.
This comment has been minimized.
|
Closing because the implementation is architecturally superseded by current main at 22f9e5e; merging this old head would restore obsolete transport code, and no unique required capability remains. |


Implements delivery-plan step 2 of https://github.com/manaflow-ai/cmux/blob/main/plans/feat-ios-iroh/DESIGN.md (iroh as the default iOS-to-Mac transport; decision 2026-06-09).
Graduates the FFI spike to
native/cmux-iroh/(iroh pinned =1.0.2, blocking C API: keygen, bind with caller-provided secret key, id, route JSON, online, accept, connect, recv, send, close; stable error-kind codes for CmxConnectFailureKind mapping; ALPNdev.cmux.mobile.terminal/0). Addsscripts/ensure-cmux-iroh.shbuilding CmuxIrohFFI.xcframework (macOS arm64+x86_64 universal, iOS device arm64, iOS sim arm64) mirroring the GhosttyKit ensure pattern, wires it into reload/setup/ios scripts, adds iOS Rust targets toscripts/install-rust-ci.sh, and provisions the toolchain across CI workflows. The xcframework links into both apps but is referenced by no code: zero behavior change.Verified: cargo build on all 4 targets; cargo test echo self-test; xcframework slice check (macOS x86_64+arm64, iOS device arm64, sim arm64); macOS compile-only tagged build; iOS arm64-sim compile-only build; pbxproj + workspace-groups + Package.resolved lints.
Part of a stacked series: P3 phone dial lane and P4 Mac host lane follow on top of this branch.
🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
Medium Risk
Large new native dependency (iroh) and broad CI/build changes affect every macOS/iOS compile; the terminal resync change touches mobile replay lifecycle but is localized and tested.
Overview
Adds
native/cmux-iroh(iroh=1.0.2) with a blocking C API for endpoint bind/connect, route JSON, and bidirectional streams, plusscripts/ensure-cmux-iroh.shto build and cacheCmuxIrohFFI.xcframework(macOS universal, iOS device/sim) like GhosttyKit. macOS and iOS Xcode projects link the xcframework and add SystemConfiguration / Security / Network (iOS) / CoreWLAN (macOS); the artifact is gitignored.CI and local builds call
ensure-cmux-iroh.shafter Rust install;install-rust-ci.shgains iOS Rust targets; release drops inlinerustupin favor of that script; setup/reload and iOS TestFlight scripts provision the FFI.Mobile shell: introduces
requestTerminalResyncso sync resyncs defer when a replay barrier owns the surface (avoids racing stale replays); the iOS test is tightened around subscribe ordering and replay ordinals.No Swift call sites into the FFI yet—link-only packaging for the iroh transport lane.
Reviewed by Cursor Bugbot for commit ff23697. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Packages the new
native/cmux-irohRust FFI intoCmuxIrohFFI.xcframeworkand wires it into scripts/CI for macOS and iOS builds. Adds a terminal replay ownership fix; the iroh framework is linked but unused, so transport behavior is unchanged.New Features
native/cmux-irohcrate (iroh=1.0.2) with a blocking C API: keygen, bind, id/route JSON, online, accept/connect, recv/send, close; stable error codes; ALPNdev.cmux.mobile.terminal/0.CmuxIrohFFI.xcframework(macOS arm64+x86_64, iOS arm64 device, iOS arm64 sim) viascripts/ensure-cmux-iroh.shwith caching; linked into macOS and iOS Xcode projects.scripts/setup.sh,scripts/reload.sh, reload-build, test (test-ios,test-e2e,test-depot), nightly, perf, macOS compat,ios-testflight,ios-app-store, and release (now usesscripts/install-rust-ci.sh); iOS lanes provision the FFI before Xcode resolves frameworks. Added Rust targets inscripts/install-rust-ci.sh(aarch64-apple-ios,aarch64-apple-ios-sim).SystemConfiguration,CoreWLAN,Security; iOSSystemConfiguration,Security,Network; ignoredCmuxIrohFFI.xcframeworkin git.Bug Fixes
requestTerminalResyncand routed resyncs through it.Written for commit ff23697. Summary will update on new commits.
Summary by CodeRabbit
New Features
Build Improvements
Bug Fixes